module UART_rx(rx_data, rdy, clr_rdy, clk, rst_n, RX);

input RX, clr_rdy, clk, rst_n;
output [7:0] rx_data;
output rdy;

//The wire used to determine when the signal goes low, signaling the start of the trasmission
wire NEGEDGE_TRANS;

reg [7:0] rx_data;
reg [1:0] STATE;
reg tmp1, tmp2, tmp3, rdy;
logic [1:0] NXT_STATE;
logic count, trans;


reg [3:0] bit_cntr;                   // need to count to 10 to include start/stop
reg [9:0] baud_cntr;                  // need 10-bits to get 921,600 from 800MHz


//The flops that hold the recieved data to determine the negedge
always @(posedge clk) begin
	tmp1 <= RX;
	tmp2 <= tmp1;
	tmp3 <= tmp2;
end

//If there is a nededge in the transmission line
assign NEGEDGE_TRANS = !tmp2 & tmp3;

//State changing
always @(posedge clk, negedge rst_n) begin

	if(!rst_n)
		STATE <= 2'b00;
	else
		STATE <= NXT_STATE;

end


//Assignment of the data to the data register, shifting in values from the line
//if the baud counter is filled and in the correct state.
always @(posedge clk, negedge rst_n) begin

	if(!rst_n)
		rx_data <= 8'h00;
	else if(STATE == 2'b10 && baud_cntr == 10'h363)
		rx_data <= {RX, rx_data[7:1]};
	else
		rx_data <= rx_data;
end

//The state logic, if there is a negedge in the line, and its idle or finished, 
//it will move to storing a new value, if its done storing a certain byte it will
//either idle or move to the next byte
always_comb begin 
	NXT_STATE = 2'b0;
	trans = 1'b0;
	case(STATE)
		2'b00: begin
			count = 1'b0;
			if(NEGEDGE_TRANS)
				NXT_STATE = 2'b01;
			else
				NXT_STATE = STATE;
		end
		2'b01: begin
			count = 1'b1;
			if(baud_cntr == 10'h1B1)
				NXT_STATE = 2'b10;
			else
				NXT_STATE = STATE;	
				
		end
		2'b10: begin
			count = 1'b1;
			trans = 1'b1;
			if(bit_cntr == 4'h8)
				NXT_STATE = 2'b11;
			else
				NXT_STATE = STATE;

		end
		2'b11: begin
			count = 1'b0;
			if(NEGEDGE_TRANS)
				NXT_STATE = 2'b01;
			else
				NXT_STATE = STATE;
		end
	endcase
end


//The ready signal is 1 if the state machine is transitioning to
//finished state if not, maintain. Clr_rdy clears.
always @(posedge clk, negedge rst_n) begin
	if(!rst_n)
		rdy <= 1'b0;
	else if(clr_rdy)
		rdy <= 1'b0;
	else if(STATE == 2'b10 && NXT_STATE == 2'b11)
		rdy <= 1'b1;
	else 
		rdy <= rdy;
end


//The baudcounter will reset if it finishes a half count in the 2nd state
//or full count in the 3rd state and will only count if it is in the read
//states
always @(posedge clk, negedge rst_n) begin
	if(!rst_n)
		baud_cntr <= 10'h000;
	else if(STATE == 2'b11 && NEGEDGE_TRANS)
		baud_cntr <= 10'h000;
	else if((STATE == 2'b10 && baud_cntr == 10'h363) || (STATE == 2'b01 && baud_cntr == 10'h1B1))
		baud_cntr <= 10'h000;
	else if(count)
		baud_cntr <= baud_cntr + 1;
end


//The bitcounter will maintain if it is the baudcounter is counting, and 
//is in the read state. It will reset if it is going to read in a new
//value. And it will increment if baudcounter is filled.
always @(posedge clk, negedge rst_n) begin
	if(!rst_n)
		bit_cntr <= 4'h0;
	else if((STATE == 2'b11) && NEGEDGE_TRANS)
		bit_cntr <= 4'h0;
	else if(baud_cntr == 10'h363)
		bit_cntr <= bit_cntr+1;
	else if(trans)
		bit_cntr <= bit_cntr;
end

endmodule	
